//  -------------------- iSharePoint -------------------- //
// 
//  Company:	IT Complex, LLC
//  Project:	Smart.Common
//  File name:	UserValueCollection.cs
//  Developer:	Solomatov Igor
//  Created:	15.04.2012
// 
//  -------------------- iSharePoint -------------------- //

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;

namespace Smart.Common.Entities
{
	/// <summary>
	/// User or group value collection
	/// </summary>
	[Serializable]
	[DebuggerStepThrough]
	public class UserValueCollection : List<UserValue>
	{
		public UserValueCollection()
		{
		}

		public UserValueCollection(IEnumerable<UserValue> collection)
			: base(collection)
		{
		}

		public UserValueCollection(int capacity)
			: base(capacity)
		{
		}

		protected void RemoveEmpty()
		{
			RemoveAll(item => item.IsEmpty);
		}

		public override string ToString()
		{
			return
				this.CastToString(SPH.MultiLookupValueDelimiter);
		}

		/// <summary>
		/// Checks whether collection is empty
		/// </summary>
		public bool IsEmpty
		{
			get { return Count <= 0; }
		}

		/// <summary>
		/// Ensure specified values exists
		/// </summary>
		/// <returns>true, if value changed</returns>
		public bool Ensure(params Identifier[] values)
		{
			var oldCount = Count;

			AddRange(values.Where(value => !value.IsEmpty).Select(value => new UserValue(value)));

			return oldCount < Count;
		}

		/// <summary>
		/// Set values
		/// </summary>
		public void Set(params Identifier[] values)
		{
			Clear();

			AddRange(values.Where(value => !value.IsEmpty).Select(value => new UserValue(value)));
		}

		/// <summary>
		/// Compare arrays by it's children Identifiers 
		/// </summary>
		public virtual bool Equals(IEnumerable<Identifier> obj)
		{
			return Equals(obj.Select(id => new UserValue(id)));
		}

		/// <summary>
		/// Compare arrays by it's children items values
		/// </summary>
		public virtual bool Equals(IEnumerable<UserValue> obj)
		{
			if (obj == null)
				return false;

			var hs = new HashSet<UserValue>(this);

			return
				hs.SetEquals(obj);
		}

		/// <summary>
		/// Calculate children items hash code
		/// </summary>
		public virtual int GetChildrenHashCode()
		{
			return
				this.Aggregate(0,
							   (code, value) =>
							   code ^ value.GetHashCode());
		}
	}
}